package top.xinsix.est.controller;

import top.xinsix.est.config.WechatConfig;
import top.xinsix.est.constants.Constants;
import top.xinsix.est.constants.ResultEnum;
import top.xinsix.est.dto.UsersDto;
import top.xinsix.est.pojo.Users;
import top.xinsix.est.service.UsersService;
import top.xinsix.est.tools.EmptyUtils;
import top.xinsix.est.tools.Result;
import top.xinsix.est.tools.ResultUtils;
import top.xinsix.est.tools.UrlUtils;
import top.xinsix.est.tools.redis.RedisKeyUtils;
import top.xinsix.est.tools.redis.RedisUtils;
import com.alibaba.fastjson.JSON;
import org.apache.log4j.Logger;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 用户Controller
 */
@RestController
@RequestMapping("/api/user")
public class UserController {
    private final static Logger logger = Logger.getLogger(UserController.class);
    @Resource
    private UsersService usersService;
    @Resource
    private RedisUtils redisUtils;
    @Resource
    private WechatConfig wechatConfig;

    @GetMapping("/login/wechat")
    public void wechatLogin(HttpServletResponse response){
        StringBuilder openBuilder = new StringBuilder(wechatConfig.getOpen_url())
                .append("?").append("appid=").append(wechatConfig.getAppid())
                .append("&").append("redirect_uri=").append(wechatConfig.getRedirect_uri())
                .append("&").append("response_type=").append(wechatConfig.getGrant_type())
                .append("&").append("scope=").append(wechatConfig.getScope())
                .append("&").append("state=").append(wechatConfig.getState());
        try {
            response.sendRedirect(openBuilder.toString());
        } catch (IOException e) {
            e.printStackTrace();
            logger.info("唤起微信登录页面失败："+e);
        }
    }
    /**
     * 微信登录——第二步：通过code换取access_token
     * @param code
     * @param request
     * @param response
     * @throws IOException
     */
    @GetMapping(value = "/wechat/callback")
    public void wechatCallback(@RequestParam String code, HttpServletRequest request, HttpServletResponse response) throws IOException{
        StringBuilder accessTokenBuilder = new StringBuilder(wechatConfig.getAccess_token_url())
                .append("?").append("appid=").append(wechatConfig.getAppid())
                .append("&").append("secret=").append(wechatConfig.getSecret())
                .append("&").append("code=").append(code)
                .append("&").append("grant_type=").append(wechatConfig.getGrant_type());
        response.setContentType("text/html;charset=utf-8");
        String json = UrlUtils.loadURL(accessTokenBuilder.toString());
        Map<String,Object> wechatToken = JSON.parseObject(json, Map.class);
        try {
            //验证本地库是否存在该用户
            String openId = wechatToken.get("openid").toString();
            String accessToken = wechatToken.get("access_token").toString();
            UsersDto user = usersService.loginByWechat(accessToken, openId);
            String token = user.getToken();
            //返回前端处理
            String loginPage = wechatConfig.getSuccess_url() + "?token=" + token;
            response.sendRedirect(loginPage);
        } catch (Exception e) {
            logger.info("微信回调错误：" , e);
        }
    }


    @PostMapping("/login/sms")
    public Result login(String phone, String sms) {
        //验证手机号 checkPhone
        if (!checkPhone(phone)) {
            logger.info("手机号码错误");
            return ResultUtils.returnFail(ResultEnum.FAIL_PARAM.getCode(), "手机号码错误");
        }
        //验证 验证码 checkSmsCode
        if (!checkSmsCode(phone, Constants.Sms.TYPE_REGIST_OR_LOGIN, sms)) {
            logger.info("验证码错误");
            return ResultUtils.returnFail(ResultEnum.FAIL_VERIFY.getCode(), "验证码错误");
        }
        //调用登录
        UsersDto usersDto = usersService.loginByPhone(phone);
        if (usersDto != null) {
            String token = usersDto.getToken();
            Map<String,String>map = new HashMap<String,String>();
            map.put("token",token);
            return ResultUtils.returnDataSuccess(map);
        }
        return ResultUtils.returnFail(ResultEnum.FAIL_ACCOUNT_NOT_EXIST.getCode(),ResultEnum.FAIL_ACCOUNT_NOT_EXIST.getMsg());
    }

    //验证手机号
    public boolean checkPhone(String phone) {
        if (EmptyUtils.isEmpty(phone)) {
            return false;
        }
        return true;
    }

    //验证验证码是否正确  正确：需要在redis存在   存在：true，不存在：false
    public boolean checkSmsCode(String phone, Integer codeType, String sms) {
        if (EmptyUtils.isEmpty(sms)) {
            return false;
        }
        //获取key
        String key = RedisKeyUtils.formatKeyWithPrefix(Constants.Redis.PREFIX_SMS, codeType.toString(), phone);
        String code = redisUtils.getValue(key);
        if (code.equals(sms)) {
            return true;
        }
        return false;
    }

    //账号密码登录
    @PostMapping("/loginByAccount")
    public Result loginByAccount(String account,String password){
        Users users = usersService.loginByAccount(account,password);
        if (users!=null)
            return ResultUtils.returnSuccess();
        return ResultUtils.returnFail();
    }
}
